package cn.gwm.flink.streaming.strategy.vehiclepredict;

import cn.gwm.flink.streaming.constant.ChargePredictFields;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.flink.api.common.state.MapState;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * @author : GW00280745
 * @date : 2022/8/12 14:54
 * @description :
 */
public class ChargeId implements Serializable {
    public ChargeId(Integer iniPointBatterVal,Integer chargeSeparatorTime){
        this.iniPointBatterVal = iniPointBatterVal;
        this.chargeSeparatorTime = chargeSeparatorTime;
    }
    public void process(JSONObject record,
                        MapState<String, String> chargeBeginState,
                        MapState<String, Long> latestTidState,
                        MapState<String, String> startPointState,
                        MapState<String, String> latestBatterState
    ){
        try {

            String vinVal = record.getString(ChargePredictFields.ins().srcFieldVin);
            Long tidVal = record.getLong(ChargePredictFields.ins().srcFieldTid);
            String vinTid = vinVal.concat(ChargePredictFields.ins().char3).concat(tidVal.toString());
            //每条记录添加一个充电组名称的字段
//            chargeGroup(record, vinVal, tidVal, vinTid,chargeBeginState,latestTidState);
            chargeGroupV2(record,vinVal);
            //每条记录添加一个起始点的字段
            frbExtract(record, vinTid,startPointState);
            //每条记录添加一个时间戳字段
            record.put(ChargePredictFields.ins().timestampField, timestamp(record.getLong(ChargePredictFields.ins().srcFieldTid)));
            String format = DateFormatUtils.format(System.currentTimeMillis(), ChargePredictFields.ins().yyyyMmddss1);
            record.put(ChargePredictFields.ins().handleTime,format);
            //充电组的最近一次的电流值
//            latestBatterState.put(record.getString(EndTempConstant.dwsField_chargeBegin),record.getString(SrcFieldsConstant.srcField_bmsBatterCurrRm))

        }catch (Exception e){
            e.printStackTrace();
            record.put(ChargePredictFields.ins().dwsFieldChargeBegin,ChargePredictFields.ins().err);
        }
    }
    private Integer iniPointBatterVal;
    private String num0Str="0";
    private String num1Str="1";
    private void frbExtract(JSONObject record, String vinTid,MapState<String, String> startPointState) throws Exception {
        String chargeId = record.getString(ChargePredictFields.ins().dwsFieldChargeBegin);
        //当前充电组如果有起始点那么跳过如果没有那么进行赋值
        if (!startPointState.contains(chargeId)){
            //如果是快充充电组中第一个电流 < -10 的记录
            BigDecimal batter = record.getBigDecimal(ChargePredictFields.ins().srcFieldBmsBatterCurrRm);
            String dc = record.getString(ChargePredictFields.ins().srcFieldBmsDcConnect);
            String obc = record.getString(ChargePredictFields.ins().srcFieldBmsObcConnect);
            int iniPointBatterValue = -10;
            if (StringUtils.equalsIgnoreCase(dc,num0Str) && StringUtils.equalsIgnoreCase(obc,num1Str)){
                //如果是慢充则是第一个电流 < -5
                iniPointBatterValue = -5;
            }
            if (batter.intValue() < iniPointBatterValue){
                record.put(ChargePredictFields.ins().dwsFieldFrbField, vinTid);
                startPointState.put(chargeId, vinTid);
            }
        }else {
            record.put(ChargePredictFields.ins().dwsFieldFrbField,startPointState.get(chargeId));
        }
    }
    private Integer chargeSeparatorTime;
    private void chargeGroupV2(JSONObject record, String vinVal) throws Exception {
        //采用充电明细中 startChargeTime 字段
        String startChargeTime = record.getString(ChargePredictFields.ins().srcFieldStartChargeTime);
        String concat = vinVal.concat(ChargePredictFields.ins().char3).concat(startChargeTime);
        record.put(ChargePredictFields.ins().dwsFieldChargeBegin, concat);
        record.put(ChargePredictFields.ins().srcFieldStartChargeTime, startChargeTime);
    }
    private void chargeGroup(JSONObject record, String vinVal, Long tidVal, String vinTid,MapState<String, String> chargeBeginState,MapState<String, Long> latestTidState) throws Exception {
        //识别充电开始点 条件1：是否是首次出现 --> 条件2：连续两条记录的tid的时间差是否大于30分钟
        //是否首次出现
        if (!chargeBeginState.contains(vinVal)){
            //当前记录就是第一次充电
            chargeBeginState.put(vinVal, vinTid);
            record.put(ChargePredictFields.ins().dwsFieldChargeBegin, vinTid);
        }else {
            //如果不包含就是非第一次充电，要判断连续tid差是否大于30分钟
            Long latestTid = latestTidState.get(vinVal);
            Long diffL = Math.abs(tidVal - latestTid);
            if (diffL != null && diffL >= chargeSeparatorTime){
                chargeBeginState.put(vinVal, vinTid);
                record.put(ChargePredictFields.ins().dwsFieldChargeBegin, vinTid);
            }else {
                record.put(ChargePredictFields.ins().dwsFieldChargeBegin,chargeBeginState.get(vinVal));
            }
        }
        latestTidState.put(vinVal, tidVal);
    }
    public Long timestamp(Long tid){
        try {
            return DateUtils.parseDate(tid.toString(), ChargePredictFields.ins().timeFormat).getTime();
        }catch (Exception e){
            e.printStackTrace();
            return 0L;
        }

    }
}
